home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / Divestiture / Source / wdef.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  3.0 KB  |  146 lines

  1. #include    "tear.h"
  2. #include    "wdef.h"
  3.  
  4. enum
  5. {
  6.     kSplitWidth = 16
  7. };
  8.  
  9. enum
  10. {
  11.     kOurWDEFSignature = 'RSGM'
  12. };
  13.  
  14. #ifdef powerc
  15. #pragma options align=mac68k
  16. #endif
  17.  
  18. typedef struct
  19. {
  20.     SInt16    bsr;
  21.     UInt32    addr;
  22.     SInt16    pop;
  23.     SInt16    fetch;
  24.     SInt16    jmp;
  25.     
  26.     UInt32    signature;
  27.     Handle    old_wdef;
  28. } defproc, **defproc_handle;
  29.  
  30. #ifdef powerc
  31. #pragma options align=reset
  32. #endif
  33.  
  34. static defproc default_dp = {
  35.     0x6104,        //        bsr.s    @1
  36.     0xFFFFFFFF,    //        dc.l    -1
  37.     0x205F,        //    @1    movea.l    (a7)+, a0
  38.     0x2050,        //        movea.l    (a0), a0
  39.     0x4ED0,        //        jmp        (a0),
  40.  
  41.     kOurWDEFSignature,
  42.     nil
  43. };
  44.  
  45. #pragma mark -
  46.  
  47. static    pascal    long    WDEF(short varCode, WindowPtr theWindow, short message, long param)
  48. {
  49.     WindowDefUPP    old_wdef_upp;
  50.     defproc_handle    dpH;
  51.     Handle            old_wdef;
  52.     long            result;
  53.     SInt8            state;
  54.     
  55.     //
  56.     //    set up to call the old WDEF. Note that we call NewRoutineDescriptor() which
  57.     //    allocates memory and may fail, but the truth is that if that would fail
  58.     //    here, worse things are about to happen (or may already have happened)!
  59.     //
  60.  
  61.     dpH = (defproc_handle)((WindowPeek)theWindow)->windowDefProc;
  62.     old_wdef = (**dpH).old_wdef;
  63.     
  64.     state = HGetState(old_wdef);
  65.     HLock(old_wdef);
  66.     old_wdef_upp = NewRoutineDescriptor((ProcPtr)*old_wdef, uppWindowDefProcInfo, kM68kISA);
  67.     result = CallWindowDefProc(old_wdef_upp, varCode, theWindow, message, param);
  68.     HSetState(old_wdef, state);
  69.     
  70.     DisposeRoutineDescriptor(old_wdef_upp);
  71.     
  72.     if (message == kWindowMsgCalculateShape)
  73.     {
  74.         WindowPeek    wp = (WindowPeek)theWindow;
  75.         RgnHandle    new_struct;
  76.                 
  77.         new_struct = NewRgn();
  78.                 
  79.         if ((gTearRgn != nil) && (new_struct != nil))
  80.         {
  81.             Point    struc_center;
  82.             Point    tear_center;
  83.             
  84.             Rect    struc_box;
  85.             Rect    tear_box;
  86.             
  87.             struc_box = (**wp->strucRgn).rgnBBox;
  88.             struc_center.h = (struc_box.right + struc_box.left) / 2;
  89.             struc_center.v = (struc_box.bottom + struc_box.top) / 2;
  90.             
  91.             tear_box = (**gTearRgn).rgnBBox;
  92.             tear_center.h = (tear_box.right + tear_box.left) / 2;
  93.             tear_center.v = (tear_box.bottom + tear_box.top) / 2;
  94.             
  95.             OffsetRgn(gTearRgn,
  96.                             struc_center.h - tear_center.h,
  97.                             struc_center.v - tear_center.v);
  98.  
  99.             DiffRgn(wp->strucRgn, gTearRgn, new_struct);
  100.             
  101.             //    we should probably not do this if the result would be empty!
  102.             if (! EmptyRgn(new_struct))
  103.                 CopyRgn(new_struct, wp->strucRgn);
  104.             
  105.             //    punch it out of the content region too
  106.             DiffRgn(wp->contRgn, gTearRgn, new_struct);
  107.             if (! EmptyRgn(new_struct))
  108.                 CopyRgn(new_struct, wp->contRgn);
  109.         }
  110.         
  111.         if (new_struct != nil)
  112.             DisposeRgn(new_struct);
  113.     }
  114.     
  115.     return result;
  116. }
  117.  
  118. #pragma mark -
  119. #pragma mark -
  120.  
  121. void    FixUpWDEF(WindowRef w)
  122. {
  123.     WindowPeek        wp = (WindowPeek)(w);
  124.     defproc_handle    wdef_h = (defproc_handle)wp->windowDefProc;
  125.     
  126.     if ((**wdef_h).signature != kOurWDEFSignature)
  127.     {
  128.         defproc_handle    new_wdef = (defproc_handle)NewHandleClear(sizeof(defproc));
  129.         
  130.         if (new_wdef != nil)
  131.         {
  132.             WindowDefUPP    upp = NewWindowDefProc(WDEF);
  133.             
  134.             (**new_wdef) = default_dp;
  135.             (**new_wdef).addr = (long)upp;
  136.             (**new_wdef).old_wdef = wp->windowDefProc;
  137.             
  138.             wp->windowDefProc = (Handle)new_wdef;
  139.         }
  140.         else
  141.         {
  142.             //    boy, are we surprised!
  143.         }
  144.     }
  145. }
  146.